package com.erp4j.dynamicfield.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.erp4j.dynamicfield.entity.FieldDefinition;
import com.erp4j.dynamicfield.entity.Order;
import com.erp4j.dynamicfield.mapper.OrderMapper;
import com.erp4j.dynamicfield.service.FieldDefinitionService;
import com.erp4j.dynamicfield.service.OrderService;
import com.erp4j.dynamicfield.vo.QueryParam;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private FieldDefinitionService fieldDefinitionService;

    @Resource
    private ObjectMapper objectMapper;

    /**
     * 分页查询订单数据
     */
    @Override
    public IPage<Order> queryByParams(Long moduleId, List<QueryParam> params, int pageNum, int pageSize) {
        Page<Order> page = new Page<>(pageNum, pageSize);

        // 获取所有字段定义，补充查询参数信息
        List<FieldDefinition> fieldDefinitions = fieldDefinitionService.getFieldsByModuleId(moduleId);

        for (QueryParam param : params) {
            // 查找对应的字段定义
            for (FieldDefinition field : fieldDefinitions) {
                if (field.getFieldName().equals(param.getFieldName())) {
                    param.setQueryType(field.getQueryType());
                    param.setFieldType(field.getFieldType());
                    // 如果是扩展字段，使用系统字段名
                    if (!field.getIsBaseField()) {
                        param.setSystemFieldName(field.getSystemFieldName());
                    }
                    break;
                }
            }
        }

        return orderMapper.queryByDynamicConditions(page, params);
    }

    /**
     * 保存或更新订单数据
     */
    @Override
    @Transactional
    public boolean saveOrUpdateOrder(Order order) {
        // 处理新建数据的默认值
        if (order.getId() == null) {
            fillDefaultValues(order);
        }
        return saveOrUpdate(order);
    }

    /**
     * 填充默认值
     */
    private void fillDefaultValues(Order order) {
        Long moduleId = order.getModuleId();
        JsonNode extFields = order.getExtFields();

        // 如果扩展字段为空，初始化一个空对象
        if (extFields == null || extFields.isNull()) {
            extFields = objectMapper.createObjectNode();
            ((ObjectNode) extFields).removeAll();
            order.setExtFields(extFields);
        }

        // 获取所有扩展字段定义
        List<FieldDefinition> extFieldDefinitions = fieldDefinitionService.getFieldsByModuleId(moduleId);

        // 填充扩展字段默认值
        for (FieldDefinition field : extFieldDefinitions) {
            String systemFieldName = field.getSystemFieldName();
            String defaultValue = field.getDefaultValue();

            // 如果字段值不存在且有默认值，则设置默认值
            if (defaultValue != null && !defaultValue.isEmpty() &&
                    (extFields.get(systemFieldName) == null || extFields.get(systemFieldName).isNull())) {
                // 根据字段类型使用不同的put方法，修复编译错误
                putValueByType((ObjectNode) extFields, systemFieldName, defaultValue, field.getFieldType());
            }
        }
    }

    /**
     * 根据字段类型放入对应的值
     */
    private void putValueByType(ObjectNode node, String fieldName, String value, String type) {
        try {
            switch (type.toLowerCase()) {
                case "number":
                case "decimal":
                    node.put(fieldName, Double.parseDouble(value));
                    break;
                case "integer":
                    node.put(fieldName, Integer.parseInt(value));
                    break;
                case "boolean":
                    node.put(fieldName, Boolean.parseBoolean(value));
                    break;
                case "date":
                    node.put(fieldName, value);
                    break;
                default:
                    node.put(fieldName, value);
            }
        } catch (Exception e) {
            node.put(fieldName, value);
        }
    }
}
